package com.zx.framework.plat.module.service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.zx.framework.core.env.CONST;
import com.zx.framework.core.exception.ServiceException;
import com.zx.framework.core.pagination.Pagination;
import com.zx.framework.core.util.StringUtil;
import com.zx.framework.db.IBaseDAO;
import com.zx.framework.db.KeyValue;
import com.zx.framework.db.exception.DatabaseException;
import com.zx.framework.plat.module.po.Module;

@Component("moduleService")
@Transactional
public class ModuleService {
	private static final Logger LOGGER = Logger.getLogger(ModuleService.class);
	@Resource
	private IBaseDAO baseDAO;
	
	/**
	 * 获取模块详细信息
	 * @param id
	 * @return
	 */
	public Module findModuleById(java.lang.String id){
		if(id==null){
			ServiceException exception = new ServiceException("模块id不能为空!");
			LOGGER.error(exception.getMessage());
			throw exception;
		}
		try {
			return baseDAO.findById(id, Module.class);
		}catch (Exception e) {
			LOGGER.error("获取模块失败！",e);
			throw new DatabaseException("获取模块失败！");
		}
	}
	
	/**
	 * 保存模块详细信息
	 * @param dept
	 * @return
	 */
	public void saveModule(Module module){
		if(module==null){
			ServiceException exception = new ServiceException("保存模块信息不能为空!");
			LOGGER.error(exception.getMessage());
			throw exception;
		}
		try {
			baseDAO.save(module);
		}catch (Exception e) {
			LOGGER.error("保存模块失败！",e);
			throw new DatabaseException("保存模块失败！");
		}
	}
	
	/**
	 * 更新模块详细信息
	 * @param dept
	 * @return
	 */
	public void updateModule(Module module){
		if(module==null){
			ServiceException exception = new ServiceException("更新模块信息不能为空!");
			LOGGER.error(exception.getMessage());
			throw exception;
		}
		try {
			baseDAO.update(module);
		}catch (Exception e) {
			LOGGER.error("修改模块失败！",e);
			throw new DatabaseException("修改模块失败！");
		}
	}
	
	/**
	 * 删除模块详细信息
	 * @param module
	 * @return
	 */
	public void removeModule(Module module){
		if(module==null){
			ServiceException exception = new ServiceException("删除模块信息不能为空!");
			LOGGER.error(exception.getMessage());
			throw exception;
		}
		try {
			baseDAO.remove(module);
		}catch (Exception e) {
			LOGGER.error("删除模块失败！",e);
			throw new DatabaseException("删除模块失败！");
		}
	}
	
	/**
	 * 分页查询模块列表信息
	 * @param example
	 * @param page
	 * @param rows
	 * @return
	 */
	public Pagination<Module> pageQuery(Module example,int page,int rows){
		String qryHql = "from com.zx.framework.plat.module.po.Module";
		String cntHql = "select count(*) from com.zx.framework.plat.module.po.Module";
		//条件查询可以放在这里 
		if(example!=null){
			//to-do
		}
		try {
			return baseDAO.hqlPageQuery(qryHql, cntHql, page, rows);
		}catch (Exception e) {
			LOGGER.error("查询模块列表失败！",e);
			throw new DatabaseException("查询模块列表失败！");
		}
	}
	/**
	 * 获取分页对象
	 * @param qrySql
	 * @param cntSql
	 * @param start
	 * @param size
	 * @param params
	 * @return
	 */
	public Pagination sqlPageQuery(String qrySql, String cntSql,
			int current, int size, Object... params) {
		return baseDAO.sqlPageQuery(qrySql, cntSql, current, size, params);
	}
	/**
	 * 执行sql语句
	 * @param sql
	 * @param params
	 * @return 记录变更条数
	 */
	public int executeSQL(String sql, Object... params) {
		try {
			return baseDAO.executeSQL(sql, params);
		}catch (Exception e) {
			LOGGER.error("执行模块 SQL更新失败！",e);
			throw new DatabaseException("执行模块更新失败！");
		}
	}
	
	/**
	 * 执行hql语句
	 * @param hql
	 * @param params
	 * @return 记录变更条数
	 */
	public int executeHQL(String hql, Object... params) {
		try {
			return baseDAO.executeHQL(hql, params);
		}catch (Exception e) {
			LOGGER.error("执行模块 HQL更新失败！",e);
			throw new DatabaseException("执行模块更新失败！");
		}
	}
	
	/**
	 * 获取sql查询列表，相当于start和size不满足判断
	 * @param sql
	 * @param params 占位参数
	 * @return java.util.Map
	 */
	public List querySQL(String sql, Object... params) {
		return baseDAO.querySQL(sql, params);
	}
	/**
	 * 获取hql查询列表
	 * @param hql
	 * @param params
	 * @return
	 */
	public List queryHQL(String hql,Object...params){
		return baseDAO.queryHQL(hql, params);
	}
	
	/**
	 * 根据属性值返回模块列表
	 * @param propertyName
	 * @param value
	 * @param orders 排序的字段名称及升降序
	 * @return
	 */
	public List findByProperty(String propertyName,
			Object value, String... orders) {
		return baseDAO.findByProperty("com.zx.framework.plat.module.po.Module", propertyName, value, orders);
	}

	/**
	 * 根据属性值返回模块列表
	 * @param queryParam
	 * @param orders 排序的字段名称及升降序
	 * @return
	 */
	public List findByProperty(KeyValue queryParam,
			String... orders) {		
		return baseDAO.findByProperty("com.zx.framework.plat.module.po.Module", queryParam, orders);
	}

	/**
	 * 根据属性值返回模块列表
	 * @param propertyName
	 * @param value
	 * @return
	 */
	public List findByProperty( String propertyName,
			Object value) {
		return baseDAO.findByProperty("com.zx.framework.plat.module.po.Module", propertyName, value);
	}

	/**
	 * 根据属性值返回模块列表
	 * @param queryParam
	 * @return
	 */
	public List findByProperty(KeyValue queryParam) {
		return baseDAO.findByProperty("com.zx.framework.plat.module.po.Module", queryParam);
	}

	/**
	 * 查找属性propertyNames值为values的数据， 所有条件求取并集，
	 * 并且按照orders进行排序，如列表中保存两项：“id desc”，“name”
	 * 表必须在hibernate中声明，返回列表为hibernate声明结构类。
	 * @param queryParams
	 * @param start
	 * @param size
	 * @param orders
	 * @return
	 */
	public List findByPropertys( List<KeyValue> queryParams,
			int start, int size, String... orders) {
		return baseDAO.findByPropertys("com.zx.framework.plat.module.po.Module", queryParams, start, size, orders);
	}

	/**
	 * 查找属性propertyNames值为values的数据， 所有条件求取并集，
	 * 并且按照orders进行排序，如列表中保存两项：“id desc”，“name”
	 * 表必须在hibernate中声明，返回列表为hibernate声明结构类。
	 * @param tableName
	 * @param queryParams
	 * @param orders
	 * @return
	 */
	public List findByPropertys(List<KeyValue> queryParams,
			String... orders) {
		return baseDAO.findByPropertys("com.zx.framework.plat.module.po.Module", queryParams, orders);
	}

	/**
	 * 返回所有模块
	 * @return
	 */
	public List findAll() {
		return baseDAO.findAll("com.zx.framework.plat.module.po.Module");
	}

	/**
	 * 返回排序的所有模块
	 * @param orders
	 * @return
	 */
	public List findAll(String... orders) {
		return baseDAO.findAll("com.zx.framework.plat.module.po.Module", orders);
	}

	/**
	 * 返回单条统计函数值 例如count 或者确实只有一条记录返回的时候
	 * @param <T>
	 * @param hql
	 * @param type
	 * @return
	 */
	public <T> T getHQLUnique(String hql, Class<T> type, Object... params) {
		return baseDAO.getHQLUnique(hql, type, params);
	}

	/**
	 * 返回单条统计函数值 例如count size 或者确实只有一条记录返回的时候
	 * @param <T>
	 * @param sql
	 * @param type
	 * @return
	 */
	public <T> T getSQLUnique(String sql, Class<T> type, Object... params) {
		return baseDAO.getSQLUnique(sql, type, params);
	}
	
	/////自定义的service方法
	/**
	 * 根据用户id获取系统的菜单
	 * @param userId
	 * @param project
	 * @return 返回当前用户可用菜单列表
	 */
	public List<Module> findUserModules(String userId,String platform,String ... project){
		return findUserModules(userId, platform, 2, project);
	}
	
	public List<Module> findUserModules(String userId,String platform,Integer operate,String ... project){
		//平台
		String suff = "";
		//项目
		String suff1 = "";
		//操作
		String suff2 = "";
		List<Object> params = new ArrayList<Object>();
		if(project!=null && project.length>0){
			params.add(new KeyValue("ids", Arrays.asList(project)));
			suff1 = " and m.projectId in (:ids) ";
		}
		params.add(new KeyValue("userId", userId));
		params.add(new KeyValue("status", CONST.OBJECT_USED));
		if(StringUtil.isNotEmpty(platform)){
			suff = " and platform = :platform ";
			params.add(new KeyValue("platform", platform));
		}
		if(operate!=null && operate!=-1){
			suff2 = " and operate != :opt ";
			params.add(new KeyValue("opt", operate));
		}
		String hql = "from Module m where 1=1 "+suff2+suff1+" and exists( from RoleModule rm where "+
				"exists (from UserRole ur where ur.id.roleId = rm.id.roleId and ur.id.userId = :userId) and "+
				"m.id = rm.id.moduleId )" +
				" and m.status = :status "+suff+" order by layer";
		return baseDAO.queryHQL(hql,params.toArray());
	}
	/**
	 * 判断用户是否有操作权限
	 * @param userId
	 * @param id
	 * @return
	 */
	public boolean hasModule(String userId,String id){
		String hql = "from Module m where m.id = ? and exists(from RoleModule rm where rm.id.moduleId = m.id and exists(from UserRole ur where ur.id.roleId = rm.id.roleId and ur.id.userId = ?))";
		return getHQLUnique(hql, Module.class, id,userId)!=null;
	}
	/**
	 * 获取bbar及tbar信息
	 * @param id
	 * @param userId
	 * @return
	 */
	public List<Module> findBarMenu(String id,String userId){
		String hql = "from Module m where m.status=? and  m.owner = ? and exists(from RoleModule rm where rm.id.moduleId = m.id and exists(from UserRole ur where ur.id.roleId = rm.id.roleId and ur.id.userId = ?)) order by layer";
		return queryHQL(hql, CONST.OBJECT_USED,id,userId);
	}
}
